package com.yaodian100.mall.member.util;

import java.util.HashMap;
import java.util.Map;

import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import org.apache.commons.lang.ArrayUtils;
import org.apache.geronimo.mail.util.Base64;
import org.apache.struts2.ServletActionContext;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.yaodian100.core.common.utils.PasswordUtils;
import com.yaodian100.core.common.utils.StringUtils;

/**
 * @author jinwei.lin
 * 
 */
public class UserData {
	public static Logger logger = LoggerFactory.getLogger(UserData.class);

	public static final String NAME_YAODIAN100_MEMBER_ID = "_1.100.D"; // 用戶序號
	public static final String NAME_YAODIAN100_LOGIN_ID = "_1.100.N"; // 用戶名稱
	public static final String NAME_YAODIAN100_LOGIN_ID_STATIC = "_1.100.SN"; // 用戶名稱
	public static final String NAME_YAODIAN100_NICKNAME = "_1.100.L"; // 用戶名稱
	public static final String NAME_YAODIAN100_IMAGE_VALID = "_1.100.IV"; // 用戶名稱
	public static final String NAME_YAODIAN100_APLLY_SOURCE = "_1.100.AS"; // 用戶來源
	public static final String NAME_YAODIAN100_CART_ITEMS = "_1.100.CI"; // 購物車商品數量
	public static final String NAME_YAODIAN100_TL_RS = "_1.100.TL"; // 限時搶購return頁面
	public static final String NAME_YAODIAN100_MEMBER_PV = "_1.100.PV"; // 用戶瀏覽記錄
	public static final String NAME_YAODIAN100_LOGIN_DOMAIN = "_1.100.LD"; // 登入网域

	public static final String KAIXIN_COOKIE_NAME = "kx_connect_session_key";
	public static final String DOMAIN_NAME = "yaodian100.com";
	public static final String CONTEXT_PATH = "/";
	public static final String NAME_YAODIAN100_SESSION_ID = "_1.100.SD"; // 用戶SESSIONID
	public static final String NAME_YAODIAN100_ALIPAY_TOKEN = "_1.100.AT"; // 支付宝快速登录Token
	public static final String NAME_YAODIAN100_360_PATHPARAM = "_1.100.3P"; // 360信任登录导回页路径

	private static final int COOKIE_TIMEOUT = 30 * 60;
	private static final int CARTID_COOKIE_TIMEOUT = 60 * 60 * 24 * 7;// 購物車cookie時間
	private static final int PAGEVIEW_COOKIE_TIMEOUT = 60 * 60 * 36;// 用戶瀏覽記錄cookie時間
	private static final int SESSION_TIMEOUT = 60 * 60 * 24 * 31;// 一个月
	private int time_out = 0;

	private HttpServletRequest request;
	private HttpServletResponse response;

	private String sessionId;

	public UserData(HttpServletRequest request, HttpServletResponse response) {
		this.request = request;
		this.response = response;
	}

	private void add(String name, String value) {
		Cookie c = new Cookie(name, value);
		c.setVersion(0);
		c.setPath(CONTEXT_PATH);
		if (NAME_YAODIAN100_LOGIN_ID.equals(name) || NAME_YAODIAN100_MEMBER_ID.equals(name)
				|| NAME_YAODIAN100_NICKNAME.equals(name) || name.equals("LTINFO") || NAME_YAODIAN100_LOGIN_DOMAIN.equals(name)) {
			if (request.getServerName().endsWith("yaodian100.com")) {
				c.setDomain(DOMAIN_NAME);
			}
		}
		if (NAME_YAODIAN100_NICKNAME.equals(name)) { //
			// 60 * 24 = 1天
			// 1 天 * 365
			c.setMaxAge(60 * 24 * 365);
		}
		if (StringUtils.equals("cartid", name)) {
			c.setMaxAge(CARTID_COOKIE_TIMEOUT);
		}
		if (NAME_YAODIAN100_MEMBER_PV.equals(name)) { //
			c.setMaxAge(PAGEVIEW_COOKIE_TIMEOUT);
		}
		if (NAME_YAODIAN100_SESSION_ID.equals(name)) {
			c.setMaxAge(SESSION_TIMEOUT);
		}
		if (time_out != 0) {
			c.setMaxAge(time_out);
		}
		c.setPath(CONTEXT_PATH);
		response.addCookie(c);
	}

	public void clear(String name) {
		Cookie c = new Cookie(name, null);
		if (NAME_YAODIAN100_SESSION_ID.equals(name) || NAME_YAODIAN100_MEMBER_PV.equals(name)
				|| NAME_YAODIAN100_LOGIN_ID.equals(name) || NAME_YAODIAN100_MEMBER_ID.equals(name)
				|| NAME_YAODIAN100_NICKNAME.equals(name) || KAIXIN_COOKIE_NAME.equals(name)
				|| NAME_YAODIAN100_LOGIN_DOMAIN.equals(name)) {
			if (request.getServerName().endsWith("yaodian100.com")) {
				c.setDomain(DOMAIN_NAME);
			} else {
				c.setDomain(request.getServerName());
			}
		}
		c.setVersion(0);
		c.setPath(CONTEXT_PATH);
		c.setMaxAge(0); // A zero value causes the cookie to be deleted.
		response.addCookie(c);
	}

	public void clearAll() {
		String[] names = getNames();
		for (int i = 0; i < names.length; i++) {
			if (NAME_YAODIAN100_MEMBER_PV.equals(names[i]) || StringUtils.equals("cartid", names[i])
					|| NAME_YAODIAN100_MEMBER_ID.equals(names[i]) || NAME_YAODIAN100_LOGIN_ID.equals(names[i])
					|| NAME_YAODIAN100_LOGIN_ID_STATIC.equals(names[i]) || KAIXIN_COOKIE_NAME.equals(names[i])
					|| NAME_YAODIAN100_LOGIN_DOMAIN.equals(names[i])) {
				clear(names[i]);
			}
			if (NAME_YAODIAN100_CART_ITEMS.equals(names[i])) {
				writeRawValue(this.NAME_YAODIAN100_CART_ITEMS, "0");
			}
		}
	}

	public void killAll() {
		String[] names = getNames();
		for (int i = 0; i < names.length; i++) {
			clear(names[i]);
		}
	}

	public void clearNickname() {
		String[] names = getNames();
		for (int i = 0; i < names.length; i++) {
			if (NAME_YAODIAN100_NICKNAME.equals(names[i])) {
				clear(names[i]);
			}
		}
	}

	public String getApplySource() {
		return readRawValue(this.NAME_YAODIAN100_APLLY_SOURCE);
	}

	/**
	 * 正常的 readValue
	 * 
	 * @param name
	 * @return
	 */
	private String getCookieValue(String name) {
		return getValue(name, false);
	}

	/**
	 * 正常的 readValue
	 * 
	 * @param name
	 * @return
	 */
	private String getDecodedCookieValue(String name) {
		return getValue(name, true);
	}

	public String getImageValid() {
		return readRawValue(this.NAME_YAODIAN100_IMAGE_VALID);
	}

	public String getLoginId() {
		return readValue(this.NAME_YAODIAN100_LOGIN_ID);
	}

	public String getLoginDamain() {
		return readRawValue(this.NAME_YAODIAN100_LOGIN_DOMAIN);
	}

	public String getMemberId() {
		return readValue(this.NAME_YAODIAN100_MEMBER_ID);
	}

	private String[] getNames() {
		Cookie[] cookies = request.getCookies();
		if (cookies == null) {
			return new String[0];
		}
		String[] names = new String[cookies.length];
		for (int i = 0; i < cookies.length; i++) {
			Cookie c = cookies[i];
			names[i] = c.getName();
		}
		return names;
	}

	public String getNickname() {
		return readValue(this.NAME_YAODIAN100_NICKNAME);
	}

	private String getValue(String name, boolean decode) {
		Cookie[] cookies = request.getCookies();
		if (cookies == null) {
			return null;
		}
		for (int i = 0; i < cookies.length; i++) {
			Cookie c = cookies[i];
			if (name.equals(c.getName())) {
				String value = c.getValue();
				if (decode) {
					return value == null ? "" : PasswordUtils.decodePassword(value, null); // 要decode
				} else {
					return value == null ? "" : value;
				}
			}
		}
		return null; // not found
	}

	/**
	 * 是否與從會員或首頁登入的使用者同一人
	 * 
	 * @param personId
	 * @return
	 */
	public boolean isLoginedUser(String loginId) {
		if (loginId == null || loginId.trim().length() == 0) {
			return false;
		}

		String loginedPid = readValue(NAME_YAODIAN100_LOGIN_ID);
		if (loginedPid != null) {
			loginedPid = loginedPid.toUpperCase();
		}
		return loginId.toUpperCase().equals(loginedPid);
	}

	public String readRawValue(String name) {
		return getCookieValue(name);
	}

	/**
	 * 視欄位從 Cookie 中或資料庫取值
	 */
	public String readValue(String name) {
		if (NAME_YAODIAN100_SESSION_ID.equals(name)) {
			sessionId = getDecodedCookieValue(name);
			return sessionId;
		} else {
			return getDecodedCookieValue(name);
		}
	}

	public void setApplySource(String value) {
		writeRawValue(this.NAME_YAODIAN100_APLLY_SOURCE, value);
	}

	public void setImageValid(String value) {
		writeRawValue(this.NAME_YAODIAN100_IMAGE_VALID, value);
	}

	public void setLoginId(String value) {
		writeValue(this.NAME_YAODIAN100_LOGIN_ID, value);
		writeRawValue(this.NAME_YAODIAN100_LOGIN_DOMAIN, request.getServerName());
		writeRawValue(this.NAME_YAODIAN100_LOGIN_ID_STATIC, new String(Base64.encode(value.getBytes())));
	}

	public void setShowName(String value) {
		writeRawValue(this.NAME_YAODIAN100_LOGIN_ID_STATIC, new String(Base64.encode(value.getBytes())));
	}

	public void setMemberId(String value) {
		writeValue(this.NAME_YAODIAN100_MEMBER_ID, value);
	}

	public void setNickname(String value) {
		writeValue(this.NAME_YAODIAN100_NICKNAME, value);
	}

	public void setRequest(HttpServletRequest request) {
		this.request = request;
	}

	public void setResponse(HttpServletResponse response) {
		this.response = response;
	}

	/**
	 * 目前不設 timeout 如果沒設 timeout 則瀏覽器關閉時會將 Cookie 給清除。
	 */
	private void setTimeout(Cookie cookie) {
		String[] timeoutList = { NAME_YAODIAN100_MEMBER_ID, NAME_YAODIAN100_LOGIN_ID, NAME_YAODIAN100_IMAGE_VALID };
		if (ArrayUtils.contains(timeoutList, cookie.getName())) {
			cookie.setMaxAge(COOKIE_TIMEOUT);
		}
	}

	public void setTimeOut(int time_out) {
		this.time_out = time_out;
	}

	private void setValue(String name, String value, boolean decode) {
		if (name == null) {
			return;
		}
		if (value == null) {
			clear(name);
		} else {
			if (decode) {
				add(name, PasswordUtils.encodePassword(value, null)); // 需要encode
			} else {
				add(name, value);
			}
		}

	}

	/**
	 * Cookie 除錯用, 印出 Cookie 中的所有內容
	 */
	@Override
	public String toString() {
		StringBuffer sb = new StringBuffer();

		Cookie[] cookies = request.getCookies();

		sb.append(getClass().getName()).append("(").append(Integer.toHexString(this.hashCode())).append(")").append(
				" : [\n");
		for (int i = 0; i < cookies.length; i++) {
			Cookie c = cookies[i];
			sb.append("    ");
			sb.append("name : ").append(c.getName()).append(", ");
			sb.append("value : ").append(c.getValue()).append(", ");
			sb.append("maxage : ").append(c.getMaxAge()).append(", ");
			sb.append("domain : ").append(c.getDomain()).append(", ");
			sb.append("path : ").append(c.getPath()).append(", ");
			sb.append("secure : ").append(c.getSecure()).append(", ");
			sb.append("comment : ").append(c.getComment()).append(", ");
			sb.append("version : ").append(c.getVersion()).append(", ");
			sb.append("\n");
		}
		sb.append("]");

		return sb.toString();
	}

	/**
	 * 不加密寫入
	 * 
	 * @param name
	 * @param value
	 */
	public void writeRawValue(String name, String value) {
		setValue(name, value, false);
	}

	/**
	 * 加密寫入
	 * 
	 * @param name
	 * @param value
	 */
	public void writeValue(String name, String value) {
		if (NAME_YAODIAN100_SESSION_ID.equals(name)) {
			sessionId = value;
		}
		setValue(name, value, true);
	}

	/**
	 * 获取HttpServletResponse
	 * 
	 * @return
	 */
	public HttpServletResponse getResponse() {
		return ServletActionContext.getResponse();
	}

	/**
	 * 获取HttpServletRequest
	 * 
	 * @return
	 */
	public HttpServletRequest getRequest() {
		return ServletActionContext.getRequest();
	}

	/**
	 * 获取HttpSession
	 * 
	 * @return
	 */
	public HttpSession getSession() {
		return getRequest().getSession();
	}

	public String getChChildCookie() {
		String data = readValue("ch_child");
		if (StringUtils.isBlank(data)) {
			String ap = getApplySource();
			if ("espnstar".equals(ap)) {
				String ltinfo = readRawValue("LTINFO");
				String m_id = readRawValue("MID");
				if (StringUtils.isNotBlank(ltinfo) && StringUtils.isNotBlank(m_id)) {
					String[] tmp = StringUtils.split(ltinfo, '|');
					data = "a_id=" + tmp[0] + "&c_id=" + tmp[1] + "&l_id=" + tmp[2] + "&l_type1=" + tmp[3] + "&m_id=" + m_id;
					writeValue("ch_child", data);
				}
			} else if ("yiqifaps".equals(ap)) {
				String fbt = readRawValue("fbt");
				String wid = readRawValue("wid");
				if (StringUtils.isNotBlank(wid)) {
					data = "fbt=" + fbt + "&wid=" + wid;
					writeValue("ch_child", data);
				}
			} else if ("fanli".equals(ap)) {
				String u_id = readRawValue("uid");
				if (StringUtils.isNotBlank(u_id)) {
					data = "u_id=" + u_id;
					writeValue("ch_child", data);
				}
			}
		}
		return data;
	}

	public Map<String, String> getChChild() {
		Map<String, String> ch_child = new HashMap<String, String>();
		String data = getChChildCookie();
		if (StringUtils.isNotBlank(data)) {
			String spdata[] = StringUtils.split(data, "&");
			for (int i = 0; i < spdata.length; i++) {
				String tmp[] = StringUtils.split(spdata[i], "=");
				ch_child.put(tmp[0], tmp[1]);
			}
		}
		return ch_child;
	}

	public String getSessionId() {
		return sessionId;
	}

	public void setSessionId(String sessionId) {
		this.sessionId = sessionId;
	}
}